// utils/token-manager.js
// 华为云Token管理器 - 缓存Token避免频繁调用

class TokenManager {
  constructor() {
    this.token = null
    this.expireTime = null
    this.isRefreshing = false
    this.pendingRequests = []
  }

  // 获取Token（优先使用缓存）
  async getToken() {
    // 检查缓存是否有效
    if (this.isTokenValid()) {
      console.log('使用缓存的Token:', this.token.substring(0, 20) + '...')
      return this.token
    }

    // 如果正在刷新Token，等待刷新完成
    if (this.isRefreshing) {
      console.log('Token正在刷新中，等待...')
      return new Promise((resolve, reject) => {
        this.pendingRequests.push({ resolve, reject })
      })
    }

    // 开始刷新Token
    this.isRefreshing = true
    console.log('开始获取新的Token...')

    try {
      const newToken = await this.fetchNewToken()
      this.setToken(newToken)
      
      // 处理等待中的请求
      this.pendingRequests.forEach(({ resolve }) => resolve(newToken))
      this.pendingRequests = []
      
      this.isRefreshing = false
      return newToken
    } catch (error) {
      // 处理等待中的请求
      this.pendingRequests.forEach(({ reject }) => reject(error))
      this.pendingRequests = []
      
      this.isRefreshing = false
      throw error
    }
  }

  // 检查Token是否有效
  isTokenValid() {
    if (!this.token || !this.expireTime) {
      return false
    }
    
    // 提前5分钟刷新Token，避免过期
    const now = Date.now()
    const refreshTime = this.expireTime - (5 * 60 * 1000) // 提前5分钟
    
    return now < refreshTime
  }

  // 设置Token和过期时间
  setToken(token) {
    this.token = token
    // Token有效期为24小时，设置过期时间为23.5小时后
    this.expireTime = Date.now() + (23.5 * 60 * 60 * 1000)
    console.log('Token已缓存，过期时间:', new Date(this.expireTime).toLocaleString())
  }

  // 清除Token缓存
  clearToken() {
    this.token = null
    this.expireTime = null
    console.log('Token缓存已清除')
  }

  // 获取Token剩余有效时间（分钟）
  getTokenRemainingTime() {
    if (!this.expireTime) {
      return 0
    }
    const remaining = this.expireTime - Date.now()
    return Math.max(0, Math.floor(remaining / (60 * 1000)))
  }

  // 从华为云获取新的Token
  async fetchNewToken() {
    return new Promise((resolve, reject) => {
      const tokenUrl = 'https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens'
      
      const tokenRequest = {
        auth: {
          identity: {
            methods: ['password'],
            password: {
              user: {
                name: 'ilieyun',
                password: 'Lieyun@2090',
                domain: {
                  name: 'ilieyun'
                }
              }
            }
          },
          scope: {
            project: {
              name: 'cn-north-4'
            }
          }
        }
      }

      console.log('获取Token请求:', tokenRequest)

      wx.request({
        url: tokenUrl,
        method: 'POST',
        data: tokenRequest,
        header: {
          'Content-Type': 'application/json'
        },
        timeout: 10000,
        success: (response) => {
          console.log('Token响应状态码:', response.statusCode)
          console.log('Token响应头:', response.header)
          console.log('Token响应数据:', response.data)

          // 检查响应状态码
          const statusCode = response.statusCode || response.status || 0
          console.log('实际状态码:', statusCode)

          // 详细检查响应头
          if (response.header) {
            console.log('响应头类型:', typeof response.header)
            console.log('响应头是否为Proxy:', response.header && response.header.constructor && response.header.constructor.name === 'Proxy')
            console.log('响应头键名列表:', Object.keys(response.header))
            console.log('查找X-Subject-Token...')
            
            // 尝试多种可能的键名
            const possibleKeys = [
              'X-Subject-Token',
              'x-subject-token',
              'X-SUBJECT-TOKEN',
              'x_subject_token',
              'subject-token',
              'Subject-Token'
            ]
            
            for (const key of possibleKeys) {
              try {
                if (response.header[key]) {
                  console.log(`找到Token，键名: ${key}`)
                  const token = response.header[key]
                  console.log('获取到新Token:', token.substring(0, 20) + '...')
                  resolve(token)
                  return
                }
              } catch (error) {
                console.log(`访问键名 ${key} 失败:`, error.message)
              }
            }
            
            // 如果没有找到，打印所有响应头内容
            console.log('所有响应头内容:')
            const headerKeys = Object.keys(response.header)
            headerKeys.forEach(key => {
              try {
                const value = response.header[key]
                console.log(`${key}: ${value}`)
              } catch (error) {
                console.log(`${key}: [无法访问]`)
              }
            })
            
            // 特别查找包含token的键名
            const tokenRelatedKeys = headerKeys.filter(key => 
              key.toLowerCase().includes('token') || 
              key.toLowerCase().includes('subject')
            )
            
            if (tokenRelatedKeys.length > 0) {
              console.log('包含token或subject的键名:', tokenRelatedKeys)
              for (const key of tokenRelatedKeys) {
                try {
                  console.log(`  ${key}: ${response.header[key]}`)
                } catch (error) {
                  console.log(`  ${key}: [无法访问]`)
                }
              }
            }
          }
          
          // 如果没有找到Token
          if (statusCode === 201 || statusCode === 200) {
            // 状态码正确但没有Token，可能是响应头问题
            console.log('状态码正确但未找到Token，检查响应头:', response.header)
            reject(new Error('Token获取成功但响应头中未找到X-Subject-Token'))
          } else {
            reject(new Error(`获取Token失败: ${statusCode}`))
          }
        },
        fail: (error) => {
          console.error('获取Token异常:', error)
          reject(error)
        }
      })
    })
  }

  // 获取Token状态信息
  getTokenStatus() {
    return {
      hasToken: !!this.token,
      isValid: this.isTokenValid(),
      remainingMinutes: this.getTokenRemainingTime(),
      isRefreshing: this.isRefreshing,
      expireTime: this.expireTime ? new Date(this.expireTime).toLocaleString() : null
    }
  }
}

// 创建全局Token管理器实例
const tokenManager = new TokenManager()

module.exports = tokenManager
